// 《围棋》作者版权所有。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package metrics

import (
	"math"
	"unsafe"
)

// ValueKind是一个表示度量值的标记，用于指示其类型。
type ValueKind int

const (
	// KindBad表示该值没有类型，不应使用。
	KindBad ValueKind = iota

	// KindUint64表示值的类型是uint64。
	KindUint64

	// KindFloat64表示值的类型是float64。
	KindFloat64

	// KindFloat64直方图表示值的类型是*Float64直方图。
	KindFloat64Histogram
)

// Value表示运行时返回的度量值。
type Value struct {
	kind    ValueKind
	scalar  uint64         // 包含标量类型的标量值。
	pointer unsafe.Pointer // 包含非标量值。
}

// Kind返回表示该值类型的标记。
func (v Value) Kind() ValueKind {
	return v.kind
}

// Uint64返回度量的内部Uint64值。如果v.Kind（）！=这种方法有点恐慌。
func (v Value) Uint64() uint64 {
	if v.kind != KindUint64 {
		panic("called Uint64 on non-uint64 metric value")
	}
	return v.scalar
}

// Float64返回度量的内部Float64值。如果v.Kind（）！=但是，这种方法会让人恐慌。
func (v Value) Float64() float64 {
	if v.kind != KindFloat64 {
		panic("called Float64 on non-float64 metric value")
	}
	return math.Float64frombits(v.scalar)
}

// float64直方图返回度量的内部*float64直方图值。如果v.Kind（）！=在直方图中，这种方法会产生恐慌。
func (v Value) Float64Histogram() *Float64Histogram {
	if v.kind != KindFloat64Histogram {
		panic("called Float64Histogram on non-Float64Histogram metric value")
	}
	return (*Float64Histogram)(v.pointer)
}
